package com.sky.service.impl;
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.*;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.*;
import com.sky.result.PageResult;
import com.sky.service.OrdersService;
import com.sky.utils.HttpClientUtil;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sun.javafx.collections.MappingChange;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

@Service
@Slf4j
public class OrdersServiceImpl implements OrdersService {
    @Value("北京市东城区长安街天安门")
    private String address;
    @Value("4wFNfgexEBUUQZipkBIdxj0YUrGgM0eG")
    private String ak;
    @Autowired
    private WebSocketServer webSocketServer;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Override
    public OrderSubmitVO userOrders(OrdersSubmitDTO ordersSubmitDTO) {
        log.info("数据是:{}",ordersSubmitDTO);
        //首先进行判断当前地址是否符合要求规范
        AddressBook addressBook = addressBookMapper.selectByIdAddress(ordersSubmitDTO.getAddressBookId().intValue());
        if (addressBook == null) {
            //如果地址为空直接抛出异常
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        //商家经纬度
        String geographical = getGeographical(address);
        //用户经纬度
        String userGeographical = getGeographical(addressBook.getProvinceName()+addressBook.getCityName()+addressBook.getDistrictName()+addressBook.getDetail());

        Long getadderss = getadderss(geographical, userGeographical);

        //进行判断购物车数据是否异常
        //根据当前用户id查询全部购物车数据
        Long currentId = BaseContext.getCurrentId();
        ShoppingCart shoppingCart = ShoppingCart.builder().userId(currentId).build();
        List<ShoppingCart> Shopping = shoppingCartMapper.list(shoppingCart);
        if (Shopping == null || Shopping.size() == 0) {
            //如果为null或空数据直接抛出异常
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        //都符合要求可以创建OrderS对象封装补全其余信息
        Orders orders = new Orders();
        //利用工具类进行复制拷贝
        BeanUtils.copyProperties(ordersSubmitDTO,orders);
        //需要补全的其他字段为
        //number
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        //status
        orders.setStatus(Orders.REFUND);
        //user_id
        orders.setUserId(currentId);
        //order_time
        orders.setOrderTime(LocalDateTime.now());
        //pay_status
        orders.setPayStatus(Orders.UN_PAID);
        //phone
        User user = userMapper.selectById(currentId);
        orders.setPhone(addressBook.getPhone());
        //address
        orders.setAddress(addressBook.getDetail());
        //user_name
        orders.setUserName(user.getName());
        //consignee
        orders.setConsignee(addressBook.getConsignee());

        //补全信息后插入吧数据插入数据库
        //插入数据后进行数据回显
        ordersMapper.insert(orders);

        //自定义集合获取购物车所有信息
        ArrayList<OrderDetail> orderDetail = new ArrayList<>();
        //我们上面已经查询到了所有的购物车信息，我们进行遍历
        for (ShoppingCart cart : Shopping) {
            //补全订单id
            OrderDetail order = new OrderDetail();
            BeanUtils.copyProperties(cart, order);
            order.setOrderId(orders.getId());
            //添加到集合中
            orderDetail.add(order);
        }
        //把集合数据插入订单明细表
        orderDetailMapper.insertBatch(orderDetail);

        //数据订单生成后，清空当前用户的购物车
        shoppingCartMapper.deleteShoppingCart(currentId);


        //封装返回数据
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(currentId)
                .orderNumber(orders.getNumber())
                .orderAmount(orders.getAmount())
                .orderTime(orders.getOrderTime())
                .build();

        Map<String ,Object> map = new HashMap<>();
        map.put("type",1);
        map.put("orderId",orders.getId());
        map.put("content","订单号"+orders.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));

        return orderSubmitVO;
    }
    @Override
    public PageResult selectHistory(OrdersPageQueryDTO ordersPageQueryDTO) {
        //用第三方插件来进行分页查询
        PageHelper.startPage(ordersPageQueryDTO.getPage(),ordersPageQueryDTO.getPageSize());
        //获取用户id
        Long currentId = BaseContext.getCurrentId();
        //查询所有的订单
        //获取到当前订单的状态
        Integer status = ordersPageQueryDTO.getStatus();
        List<OrderVO> orderVO;
        if (status == null){
            orderVO = ordersMapper.select(currentId);
        }else {
            orderVO = ordersMapper.selectAll(currentId, status);
        }
        //遍历查询的数据，获取到用下单时间进行比较，如果超出我们设置的时间就进入判断做修改
        for (OrderVO vo : orderVO) {
            LocalDateTime orderTime = vo.getOrderTime();
            //获取当前毫秒值
            long milli = orderTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
            log.info(milli + "-----------");
            //如果9000毫秒后还是未支付状态会进行修改
            log.info(System.currentTimeMillis() + "===================");
            if (System.currentTimeMillis() >(milli + (1000*60*15))){
                if (vo.getStatus() == 1){
                    ordersMapper.updateOrdersStstus(vo);
                }
            }
        }
            Page pa = (Page) orderVO;
            if (orderVO != null) {
                //查询订单详情菜品
                for (OrderVO vo : orderVO) {
                    //获取订单id
                    Long id = vo.getId();
                    //根据订单id查询所有菜品详情
                    List<OrderDetail> orderDetailList = orderDetailMapper.selectAll(id);
                    for (OrderDetail orderDetail : orderDetailList) {
                        String name = orderDetail.getName();
                        vo.setOrderDishes(name);
                    }
                    //数据添加进vo
                    vo.setOrderDetailList(orderDetailList);
                }
            }

        //封装返回
        PageResult pageResult = new PageResult();
        pageResult.setTotal(pa.getTotal());
        pageResult.setRecords(pa.getResult());
        log.info("分页结果：{}",pageResult);

        return pageResult;

    }
    @Override
    public OrderVO selectById(Integer id) {
        //根据当前订单的id查询当前订单信息
        Orders orders = ordersMapper.selectById(id);
        //根据当前订单的id，去查询订单的详情信息
        List<OrderDetail> orderDetailList = orderDetailMapper.selectAll(id.longValue());
        OrderVO orderVO = new OrderVO();

        for (OrderDetail orderDetail : orderDetailList) {
            String name = orderDetail.getName();
            orderVO.setOrderDishes(name);
        }

        BeanUtils.copyProperties(orders,orderVO);
        orderVO.setOrderDetailList(orderDetailList);
        return orderVO;
    }
    @Override
    public void updateOrdersStstus(Integer id) {
        //更改当前订单的状态进行修改
        Orders orders = ordersMapper.selectById(id);
        orders.setStatus(Orders.CANCELLED);
        ordersMapper.updateOrdersStstus(orders);
    }

    @Override
    public void OneMoreOrder(Integer id) {
        //根据订单id查询到订单详情数据
        List<OrderDetail> orderDetailList = orderDetailMapper.selectAll(id.longValue());
        //根据订单号去查询当前用户user_id
        Orders orders = ordersMapper.selectById(id);
        //遍历所菜品添加到购物车中
        for (OrderDetail orderDetail : orderDetailList) {
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(orderDetail,shoppingCart);
            //补全其他信息
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCart.setUserId(orders.getUserId());
            shoppingCartMapper.insert(shoppingCart);
        }
    }
    @Override
    public PageResult selectOrderDetails(OrdersPageQueryDTO ordersPageQueryDTO) {
        //先进行分页数据
        PageHelper.startPage(ordersPageQueryDTO.getPage(),ordersPageQueryDTO.getPageSize());
        List<OrderVO> orderss = ordersMapper.selectPage(ordersPageQueryDTO);
        for (OrderVO orderss1 : orderss) {
            List<OrderDetail> orderDetailList = orderDetailMapper.selectAll(orderss1.getId());
            //设置拼接菜名
            StringJoiner sj = new StringJoiner(";");
            for (OrderDetail orderDetail : orderDetailList) {
                sj.add(orderDetail.getName() + "*" + orderDetail.getNumber());
            }
            orderss1.setOrderDishes(sj.toString());
            LocalDateTime oldTime = orderss1.getOrderTime().plusMinutes(15);




            if (LocalDateTime.now().isAfter(oldTime)){
                orderss1.setStatus(Orders.CANCELLED);
                orderss1.setCancelReason(MessageConstant.ORDER_TIMED_OUT);
                orderss1.setCancelTime(LocalDateTime.now());
                ordersMapper.updateOrdersStstus(orderss1);
            }
        }



        Page page = (Page) orderss;


        return new PageResult(page.getTotal(), page.getResult());
    }
    /**
     * 调用
     * @param id
     * @return
     */
    @Override
    public OrderVO ViewOrderDetails(Integer id) {
        //根据当前订单的id查询当前订单信息
        Orders orders = ordersMapper.selectById(id);
        //根据当前订单的id，去查询订单的详情信息
        List<OrderDetail> orderDetailList = orderDetailMapper.selectAll(id.longValue());
        OrderVO orderVO = new OrderVO();

        for (OrderDetail orderDetail : orderDetailList) {

            String name = orderDetail.getName();
            orderVO.setOrderDishes(name);
        }

        BeanUtils.copyProperties(orders,orderVO);
        orderVO.setOrderDetailList(orderDetailList);
        return orderVO;
    }

    /**
     * 各个状态的订单数量统计
     * //待接单数量
     *  toBeConfirmed;
     *
     * 待派送数量
     * confirmed;
     *
     *  派送中数量
     *   deliveryInProgress;
     * @return
     */
    @Override
    public OrderStatisticsVO getStatistics() {
        //2待接单 3已接单 4派送中
        //2待接单 3已接单 4派送中
        int toBeConfirmed = 0;
        int confirmed = 0;
        int deliveryInProgress = 0;

        //获取待接单的数量
        //根据下单用户id查询订单信息
        Long currentId = BaseContext.getCurrentId();

        List<Orders> orders = ordersMapper.selectOrders(currentId);

        for (Orders order : orders) {
            if (order.getStatus() == 2){
                toBeConfirmed++;
            }else if (order.getStatus() == 3){
                confirmed++;
            }else if (order.getStatus() == 4) {
                deliveryInProgress++;
            }
        }
        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        orderStatisticsVO.setConfirmed(confirmed);
        orderStatisticsVO.setDeliveryInProgress(deliveryInProgress);
        orderStatisticsVO.setToBeConfirmed(toBeConfirmed);
        return orderStatisticsVO;
    }

    /**
     * 取消订单
     * @param ordersCancelDTO
     */
    @Override
    public void CancelTheOrder(OrdersCancelDTO ordersCancelDTO) {
        extracted(ordersCancelDTO.getId().intValue(),ordersCancelDTO.getCancelReason());
    }

    /**
     * 拒绝订单
     * @param ordersRejectionDTO
     */
    @Override
    //订单id
    public void Declines(OrdersRejectionDTO ordersRejectionDTO) {
        extracted(ordersRejectionDTO.getId().intValue(),ordersRejectionDTO.getRejectionReason());
    }

    /**
     * 接单
     * @param
     * ordersConfirmDTO
     */
    @Override
    public void TakeOrders(OrdersConfirmDTO ordersConfirmDTO) {
        //根据订单id获取订单
        Orders orders = ordersMapper.selectById(ordersConfirmDTO.getId().intValue());
        orders.setStatus(Orders.CONFIRMED);
        ordersMapper.updateOrdersStstus(orders);
    }

    /**
     * 完成功能
     * @param id
     */
    @Override
    public void finish(Integer id) {
        //根据订单id获取订单
        Orders orders = ordersMapper.selectById(id);
        orders.setStatus(Orders.COMPLETED);
        ordersMapper.updateOrdersStstus(orders);
    }

    /**
     * 派送功能
     * @param id
     */
    @Override
    public void Delivery(Integer id) {
        Orders orders = ordersMapper.selectById(id);
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        ordersMapper.updateOrdersStstus(orders);
    }

    /**
     * 相同代码提取
     * @param id
     * @param name
     */
    private void extracted(Integer id,String name) {
        //先获取订单详情，根据前端传来的取消原因，来重新设置进去
        Orders orders = ordersMapper.selectById(id);
        orders.setCancelReason(name);
        //并进行修改状态值
        orders.setStatus(Orders.SEVEN);
        orders.setCancelTime(LocalDateTime.now());
        ordersMapper.updateOrdersStstus(orders);
    }

    //优化地理位置，5公里以外的不接单
    //获取经纬度的方法
    public String getGeographical(String userAddress){
        //支付宝获取商家或用户的经纬度地址
        String url = "https://api.map.baidu.com/geocoding/v3/";
        //创建一个map集合
        Map map = new HashMap();

        map.put("address",userAddress);
        map.put("ak",ak);
        map.put("output","json");
        String doGet = HttpClientUtil.doGet(url, map);

        JSONObject jsonObject = JSONObject.parseObject(doGet);
        log.info("输出是:{}",jsonObject);

        if (!jsonObject.getString("status").equals("0")){
            throw new OrderBusinessException("经纬度解析错误");
        }

        JSONObject result = jsonObject.getJSONObject("result");
        JSONObject location = result.getJSONObject("location");
        //纬度值
        Double lat = location.getDouble("lat");
        //纬度值
        Double lng = location.getDouble("lng");

        StringBuilder sb =  new StringBuilder();
        //商家的经纬度
        String string = sb.append(lat).append(",").append(lng).toString();

        return string;
    }
    public Long getadderss(String geographical,String userGeographical){
        //https://api.map.baidu.com/directionlite/v1/driving
        String url = "https://api.map.baidu.com/directionlite/v1/driving";

        Map map = new HashMap();

        map.put("origin",geographical);
        map.put("ak",ak);
        map.put("output","json");
        map.put("destination",userGeographical);

        String doGet = HttpClientUtil.doGet(url, map);

        JSONObject jsonObject = JSONObject.parseObject(doGet);

        if (!jsonObject.getString("status").equals("0")){
            throw new OrderBusinessException("异常");
        }

        JSONObject result = jsonObject.getJSONObject("result");
        JSONArray routes = (JSONArray) result.get("routes");

        JSONObject o = (JSONObject) routes.get(0);
        Long distance = o.getLong("distance");


        if (distance > 5000){
            throw new OrderBusinessException("配送超过范围");
        }

        return distance;
    }


    /**
     * 催单
     * @param id
     */

    @Override
    public void reminder(Long id) {
        //完成催单
        //通过id获取订单信息
        Orders orders = ordersMapper.selectById(id.intValue());

        //判断订单是否存在
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        //如果存在，构建json数据使用websocket发送到客户端
        Map<String,Object> map = new HashMap();
        map.put("type",2);
        map.put("orderId",id);
        map.put("content", "订单号：" + orders.getNumber());

        webSocketServer.sendToAllClient(JSON.toJSONString(map));
    }

}
